﻿using System;
using System.ComponentModel;
using System.Globalization;
using System.Reflection;
using Pfz.Extensions;

namespace Pfz.WpfControls
{
	/// <summary>
	/// Converts a property info to and from strings.
	/// </summary>
	public class PropertyInfoConverter:
		TypeConverter
	{
		/// <summary>
		/// Returns true for strings.
		/// </summary>
		public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
		{
			//MessageBox.Show("CanConvertFrom " + sourceType.FullName);
			return sourceType == typeof(string);
		}

		/// <summary>
		/// Returns true for strings.
		/// </summary>
		public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
		{
			//MessageBox.Show("CanConvertTo " + destinationType.FullName);
			return destinationType == typeof(string);
		}
		
		/// <summary>
		/// Gets the property info from a string representation.
		/// The fulltypename.PropertyName should be used.
		/// </summary>
		public static PropertyInfo ConvertFrom(string propertyFullName)
		{
			if (propertyFullName == null)
				throw new ArgumentNullException("propertyFullName");

			int lastIndex = propertyFullName.LastIndexOf('.');
			if (lastIndex == -1)
				throw new ArgumentException("You must pass the fullname of the type, plus a dot and the name of the property.");
			
			string typeName = propertyFullName.Substring(0, lastIndex);
			string propertyName = propertyFullName.Substring(lastIndex + 1);
			foreach(var assembly in AppDomain.CurrentDomain.GetAssemblies())
			{
				Type type = assembly.GetType(typeName, false);
				if (type != null)
				{
					var propertyInfo = type.GetInterfaceProperty(propertyName);
					
					return propertyInfo;
				}
			}

			throw new ArgumentException("Type " + typeName + " not found. Remember, after the type name you must pass the property name.");
		}

		/// <summary>
		/// Gets the property info from a string representation.
		/// The fulltypename.PropertyName should be used.
		/// </summary>
		public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
		{
			string strValue = value as string;
			if (string.IsNullOrEmpty(strValue))
				return null;
			
			return ConvertFrom(strValue);
		}
		
		/// <summary>
		/// Gets the string representation of a propertyInfo.
		/// </summary>
		public static string ConvertTo(PropertyInfo propertyInfo)
		{
			if (propertyInfo == null)
				return null;
			
			return string.Concat
			(
				propertyInfo.DeclaringType.FullName,
				'.',
				propertyInfo.Name
			);
		}

		/// <summary>
		/// Gets the string representation of a propertyInfo.
		/// </summary>
		public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
		{
			var recordProperty = value as PropertyInfo;
			return ConvertTo(recordProperty);
		}
	}
}
